package com.ship.dispatch.util;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ship.common.core.constant.ShipApiConstants;
import com.ship.common.core.mapping.Label;
import com.ship.common.core.utils.OkHttpUtil;
import com.ship.dispatch.bean.*;
import com.ship.dispatch.bo.ShipRentYearInfoBO;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Component
public class CommonUtil {

    private static String shipServerHost;


    private static String shipServerAppKey;

    @Value("${ship_server.host}")
    public void setShipServerHost(String shipServerHost) {
        this.shipServerHost = shipServerHost;
    }

    @Value("${ship_server.app_key}")
    public void setShipServerAppKey(String shipServerAppKey) {
        this.shipServerAppKey = shipServerAppKey;
    }

    /**
     * 获取船只年度租入租出信息
     * @param ship
     * @param year
     * @return
     */
    public static ShipRentYearInfoBO getShipYearTradeInfo(SpInformation ship, Integer year){
        Date yearStartDate = DateUtil.parseDate(year+"-01-01");
        Date yearEndDate = DateUtil.parseDate(year+"-12-31");

        ShipRentYearInfoBO infoBO = new ShipRentYearInfoBO();
        if(StringUtils.isBlank(ship.getRentTimeSlot())){
            return infoBO;
        }
        BigDecimal yearInRentDays = BigDecimal.ZERO;
        BigDecimal yearInRentMoney = BigDecimal.ZERO;
        BigDecimal yearOutRentDays = BigDecimal.ZERO;
        BigDecimal yearOutRentMoney = BigDecimal.ZERO;
        JSONArray arrar = JSONArray.parseArray(ship.getRentTimeSlot());
        for (Object o : arrar) {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(o));
            if(jsonObject.get("租入长期船") != null){
                JSONArray rentArray = jsonObject.getJSONArray("租入长期船");
                for (Object o1 : rentArray) {
                    JSONObject rentJson = JSONObject.parseObject(JSON.toJSONString(o1));
                    Date startDate = DateUtil.parseDate(rentJson.getString("rentDateBegin"));
                    Date endDate = DateUtil.parseDate(rentJson.getString("rentDateEnd"));
                    BigDecimal money = new BigDecimal(rentJson.getString("rentParagraph"));

                    if(startDate.after(yearEndDate) || endDate.before(yearStartDate)){
                        continue;
                    }

                    Date bDate = yearStartDate.after(startDate) ? yearStartDate : startDate;
                    Date eDate = yearEndDate.before(endDate) ? yearEndDate : endDate;
                    if(bDate.after(eDate)){
                        //租期不在当前时间区间内，不需要纳入计算
                        continue;
                    }
                    BigDecimal days = new BigDecimal(String.valueOf(DateUtil.betweenDay(bDate,eDate,true)));
                    yearInRentDays = yearInRentDays.add(days);
                    yearInRentMoney = yearInRentMoney.add(days.multiply(money));
                }
            }else if(jsonObject.get("租入短期船") != null){
                JSONArray rentArray = jsonObject.getJSONArray("租入短期船");
                for (Object o1 : rentArray) {
                    JSONObject rentJson = JSONObject.parseObject(JSON.toJSONString(o1));
                    Date startDate = DateUtil.parseDate(rentJson.getString("rentDateBegin"));
                    Date endDate = DateUtil.parseDate(rentJson.getString("rentDateEnd"));
                    BigDecimal money = new BigDecimal(rentJson.getString("rentParagraph"));
                    if(startDate.after(yearEndDate) || endDate.before(yearStartDate)){
                        continue;
                    }
                    Date bDate = yearStartDate.after(startDate) ? yearStartDate : startDate;
                    Date eDate = yearEndDate.before(endDate) ? yearEndDate : endDate;
                    if(bDate.after(eDate)){
                        //租期不在当前时间区间内，不需要纳入计算
                        continue;
                    }
                    BigDecimal days = new BigDecimal(String.valueOf(DateUtil.betweenDay(bDate,eDate,true)));
                    yearInRentDays = yearInRentDays.add(days);
                    yearInRentMoney = yearInRentMoney.add(days.multiply(money));
                }
            }else if(jsonObject.get("船舶租出") != null){
                JSONArray rentArray = jsonObject.getJSONArray("船舶租出");
                for (Object o1 : rentArray) {
                    JSONObject rentJson = JSONObject.parseObject(JSON.toJSONString(o1));
                    Date startDate = DateUtil.parseDate(rentJson.getString("rentDateBegin"));
                    Date endDate = DateUtil.parseDate(rentJson.getString("rentDateEnd"));
                    BigDecimal money = new BigDecimal(rentJson.getString("rentParagraph"));
                    if(startDate.after(yearEndDate) || endDate.before(yearStartDate)){
                        continue;
                    }
                    Date bDate = yearStartDate.after(startDate) ? yearStartDate : startDate;
                    Date eDate = yearEndDate.before(endDate) ? yearEndDate : endDate;
                    if(bDate.after(eDate)){
                        //租期不在当前时间区间内，不需要纳入计算
                        continue;
                    }
                    BigDecimal days = new BigDecimal(String.valueOf(DateUtil.betweenDay(bDate,eDate,true)));
                    yearOutRentDays = yearOutRentDays.add(days);
                    yearOutRentMoney = yearOutRentMoney.add(days.multiply(money));
                }
            }
        }
        infoBO.setYearInRentDays(yearInRentDays);
        infoBO.setYearInRentMoney(yearInRentMoney);
        infoBO.setYearOutRentDays(yearOutRentDays);
        infoBO.setYearOutRentMoney(yearOutRentMoney);
        return infoBO;
    }

    /**
     * 获取港口查询信息
     * @param portInformation
     * @return
     */
    public static String getPortThirdId(SpPortInformation portInformation){
        String keyWords = "";
        if(portInformation.getPortType().intValue() == 1){
            keyWords = portInformation.getPortNameEnglish();
        }else{
            keyWords = portInformation.getParentPortName();
        }
        if(StringUtils.isBlank(keyWords)){
            return null;
        }
        JSONObject paramJson = new JSONObject();
        paramJson.put("keyword",keyWords);
        RequestBody body = RequestBody.create(paramJson.toJSONString(),MediaType.parse("application/json"));
        Map<String, String> headers = new HashedMap<>();
        headers.put("AppKey",shipServerAppKey);
        Object resultObj = OkHttpUtil.sendOkHttpClient(shipServerHost+ ShipApiConstants.EXAPI_SHIPPORT_QUERY
                , "POST",body,headers);
        System.out.println("查询结果=============="+resultObj);

        if(resultObj == null){
            return null;
        }
        JSONObject resultJson = JSONObject.parseObject(String.valueOf(resultObj));
        if(!StringUtils.equals("0",resultJson.getString("code"))){
            return null;
        }

        JSONArray jsonArray = resultJson.getJSONArray("data");
        if(jsonArray.size() == 0){
            return null;
        }
        JSONObject distanceJson = JSONObject.parseObject(jsonArray.get(0).toString());
        String thirdPortId = distanceJson.getString("portId");
        return thirdPortId;
    }

    /**
     * 重新生成航次号和货号
     *
     * @param detailList
     * @return
     */
    public static List<SpYearPlanSchemeDetail> resetVoyageNoAndGoodsNumber(List<SpYearPlanSchemeDetail> detailList) {
        detailList = detailList.stream().sorted(Comparator.comparing(SpYearPlanSchemeDetail::getExpectedLoadingDate)).collect(Collectors.toList());

        for (int i = 1; i <= detailList.size(); i++) {
            SpYearPlanSchemeDetail detail = detailList.get(i - 1);
            //重新生成航次号
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(detail.getExpectedLoadingDate());
            int year = calendar.get(Calendar.YEAR);
            String num = i > 9 ? ""+i : "0"+i;
            detail.setVoyageNo("CNOOC" + year + "" + num);
            detail.setSchemeNumber(i);
        }
        List<SpYearPlanSchemeDetail> saveList = new LinkedList<>();
        //根据资源方分组重新生成各个资源方的货号
        Map<String, List<SpYearPlanSchemeDetail>> detailMap = detailList.stream().collect(Collectors.groupingBy(SpYearPlanSchemeDetail::getSeller));
        for (String seller : detailMap.keySet()) {
            List<SpYearPlanSchemeDetail> mapDetails = detailMap.get(seller);
            mapDetails = mapDetails.stream().sorted(Comparator.comparing(SpYearPlanSchemeDetail::getExpectedLoadingDate)).collect(Collectors.toList());
            for (int i = 1; i <= mapDetails.size(); i++) {
                SpYearPlanSchemeDetail mapDetail = mapDetails.get(i - 1);
                String num = i > 9 ? ""+i : "0"+i;
                mapDetail.setGoodsNum(seller + "FOB" + num);
                saveList.add(mapDetail);
            }
        }
        return saveList;
    }

    /**
     * 重新生成航次号和货号
     *
     * @param detailList
     * @return
     */
    public static List<SpDispatchPotentialSchemeDetail> resetVoyageNoAndGoodsNumberPotential(List<SpDispatchPotentialSchemeDetail> detailList) {
        Map<Integer,List<SpDispatchPotentialSchemeDetail>> allDetailMap = detailList.stream().collect(Collectors.groupingBy(SpDispatchPotentialSchemeDetail::getPlanYear));
        List<SpDispatchPotentialSchemeDetail> saveList = new LinkedList<>();
        for (Integer year : allDetailMap.keySet()) {
            List<SpDispatchPotentialSchemeDetail> yearDetailList = allDetailMap.get(year);
            yearDetailList = yearDetailList.stream().sorted(Comparator.comparing(SpDispatchPotentialSchemeDetail::getExpectedLoadingDate)).collect(Collectors.toList());

            for (int i = 1; i <= yearDetailList.size(); i++) {
                SpDispatchPotentialSchemeDetail detail = yearDetailList.get(i - 1);
                //重新生成航次号
                String num = i > 9 ? ""+i : "0"+i;
                if(StringUtils.isNotBlank(detail.getSellerContractName()) && detail.getSellerContractName().indexOf("返装销售") > -1){
                    num = (num + "R");
                }
                detail.setVoyageNo("CNOOC" + year + "" + num);
                detail.setSchemeNumber(i);
            }

            //根据资源方分组重新生成各个资源方的货号
            Map<String, List<SpDispatchPotentialSchemeDetail>> detailMap = yearDetailList.stream().collect(Collectors.groupingBy(SpDispatchPotentialSchemeDetail::getSeller));
            for (String seller : detailMap.keySet()) {
                List<SpDispatchPotentialSchemeDetail> mapDetails = detailMap.get(seller);
                mapDetails = mapDetails.stream().sorted(Comparator.comparing(SpDispatchPotentialSchemeDetail::getExpectedLoadingDate)).collect(Collectors.toList());
                for (int i = 1; i <= mapDetails.size(); i++) {
                    SpDispatchPotentialSchemeDetail mapDetail = mapDetails.get(i - 1);
                    String num = i > 9 ? ""+i : "0"+i;
                    if(StringUtils.isNotBlank(mapDetail.getSellerContractName()) && mapDetail.getSellerContractName().indexOf("返装销售") > -1){
                        num = (num + "R");
                    }
                    mapDetail.setGoodsNum(seller + "FOB" + num);
                    saveList.add(mapDetail);
                }
            }
        }
        return saveList;
    }

    /**
     * 重新生成航次号和货号
     *
     * @param detailList
     * @return
     */
    public static List<SpDispatchSchemeDetail> resetVoyageNoAndGoodsNumberDispatch(List<SpDispatchSchemeDetail> detailList) {
        Map<Integer,List<SpDispatchSchemeDetail>> allDetailMap = detailList.stream().collect(Collectors.groupingBy(SpDispatchSchemeDetail::getPlanYear));
        List<SpDispatchSchemeDetail> saveList = new LinkedList<>();
        for (Integer year : allDetailMap.keySet()) {
            List<SpDispatchSchemeDetail> yearDetailList = allDetailMap.get(year);
            yearDetailList = yearDetailList.stream().sorted(Comparator.comparing(SpDispatchSchemeDetail::getExpectedLoadingDate)).collect(Collectors.toList());

            //区分已下发和未下发
            List<SpDispatchSchemeDetail> sendList = yearDetailList.stream().filter(detail -> StringUtils.isNotBlank(detail.getAssigner())).collect(Collectors.toList());
            List<SpDispatchSchemeDetail> unSendList = yearDetailList.stream().filter(detail -> StringUtils.isBlank(detail.getAssigner())).collect(Collectors.toList());

            int sendSize = sendList.size();

            for (int i = 1 + sendSize; i <= unSendList.size() + sendSize; i++) {
                SpDispatchSchemeDetail detail = unSendList.get(i - sendSize - 1);
                //重新生成航次号
                String num = i > 9 ? ""+i : "0"+i;
                if(StringUtils.isNotBlank(detail.getSellerContractName()) && detail.getSellerContractName().indexOf("返装销售") > -1){
                    num = (num + "R");
                }
                detail.setVoyageNo("CNOOC" + year + "" + num);
                detail.setSchemeNumber(i);
            }

            List<SpDispatchSchemeDetail> newDetailList = new LinkedList<>();
            newDetailList.addAll(sendList);
            newDetailList.addAll(unSendList);

            //根据资源方分组重新生成各个资源方的货号
            Map<String, List<SpDispatchSchemeDetail>> detailMap = newDetailList.stream().collect(Collectors.groupingBy(SpDispatchSchemeDetail::getSeller));
            for (String seller : detailMap.keySet()) {
                List<SpDispatchSchemeDetail> mapDetails = detailMap.get(seller);
                mapDetails = mapDetails.stream().sorted(Comparator.comparing(SpDispatchSchemeDetail::getExpectedLoadingDate)).collect(Collectors.toList());

                //区分已下发和未下发
                List<SpDispatchSchemeDetail> sendGoodsList = mapDetails.stream().filter(detail -> StringUtils.isNotBlank(detail.getAssigner())).collect(Collectors.toList());
                List<SpDispatchSchemeDetail> unSendGoodsList = mapDetails.stream().filter(detail -> StringUtils.isBlank(detail.getAssigner())).collect(Collectors.toList());

                int sendGoodsSize = sendGoodsList.size();
                for (int i = 1 + sendGoodsSize; i <= unSendGoodsList.size() + sendGoodsSize; i++) {
                    SpDispatchSchemeDetail mapDetail = unSendGoodsList.get(i - sendGoodsSize - 1);
                    String num = i > 9 ? ""+i : "0"+i;
                    if(StringUtils.isNotBlank(mapDetail.getSellerContractName()) && mapDetail.getSellerContractName().indexOf("返装销售") > -1){
                        num = (num + "R");
                    }
                    mapDetail.setGoodsNum(seller + "FOB" + num);
                    saveList.add(mapDetail);
                }
                saveList.addAll(sendGoodsList);
            }
        }
        return saveList;
    }

    /**
     * 获取标签值
     * @param field
     * @return
     */
    public static String getFieldLabel(Field field) {
        Label labelAnnotation = field.getAnnotation(Label.class);
        if (labelAnnotation != null) {
            String[] labelValues = labelAnnotation.value();
            if (labelValues.length > 0) {
                return labelValues[0]; // 返回数组的第一个元素作为Label值
            }
        }
        return field.getName(); // 如果注解不存在或者数组为空，返回字段名作为默认值
    }
}
